package zxs.sino.elite.hub.utils;

import com.aliyun.apache.hc.core5.http.HttpStatus;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import zxs.sino.elite.hub.config.OtherConfig;
import zxs.sino.elite.hub.exception.BizCodeEnums;

import java.util.HashMap;
import java.util.Map;

/**
 * 返回数据
 *
 * @author zhang
 */
public class R extends HashMap<String, Object> {
    private static final long serialVersionUID = 1L;
    // Jackson ObjectMapper实例，线程安全
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
    
    static {
        // 设置日期格式
        java.text.SimpleDateFormat dateFormat = new java.text.SimpleDateFormat(OtherConfig.DATETIME_FORMAT);
        OBJECT_MAPPER.setDateFormat(dateFormat);
        // 禁用序列化日期为时间戳
        OBJECT_MAPPER.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    }

    public R() {
        put("code", 0);
        put("msg", "success");
    }

    /**
     * 封装数据
     */
    public R setData(Object data) {
        return put("data", data);
    }

    /**
     * 解析数据
     * 1.@ResponseBody返回类型被封装成了Json格式
     * 2.feign接收参数时也会封装成json格式，data对象也被解析成json格式的数据（[集合对象]或{map对象}）
     * 3.将data转成json字符串格式，然后再解析成对象
     */
    public <T> T getData(TypeReference<T> type) {
        Object data = get("data");
        if (data == null) {
            return null;
        }
        try {
            // 如果数据已经是目标类型，直接返回
            if (type.getType().equals(data.getClass())) {
                return (T) data;
            }
            // 先序列化为JSON字符串，再反序列化为目标类型
            String jsonString = OBJECT_MAPPER.writeValueAsString(data);
            return OBJECT_MAPPER.readValue(jsonString, type);
        } catch (Exception e) {
            throw new RuntimeException("Failed to parse data to the specified type", e);
        }
    }

    /**
     * 解析数据
     */
    public <T> T getData(String key, TypeReference<T> type) {
        Object data = get(key);
        if (data == null) {
            return null;
        }
        try {
            // 如果数据已经是目标类型，直接返回
            if (type.getType().equals(data.getClass())) {
                return (T) data;
            }
            // 先序列化为JSON字符串，再反序列化为目标类型
            String jsonString = OBJECT_MAPPER.writeValueAsString(data);
            return OBJECT_MAPPER.readValue(jsonString, type);
        } catch (Exception e) {
            throw new RuntimeException("Failed to parse data from key '" + key + "' to the specified type", e);
        }
    }

    public static R error() {
        return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常，请联系管理员");
    }

    public static R error(String msg) {
        return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg);
    }

    public static R error(int code, String msg) {
        R r = new R();
        r.put("code", code);
        r.put("msg", msg);
        return r;
    }

    public static R error(BizCodeEnums bizCode) {
        return error(bizCode.getCode(), bizCode.getMsg());
    }

    public static R ok(String msg) {
        R r = new R();
        r.put("msg", msg);
        return r;
    }

    public static R ok(Map<String, Object> map) {
        R r = new R();
        r.putAll(map);
        return r;
    }

    public static R ok() {
        return new R();
    }

    public R put(String key, Object value) {
        super.put(key, value);
        return this;
    }

    public Integer getCode() {
        return (Integer) this.get("code");
    }
}
